#include <jni.h>
#include <string>
#include "mp3lame/lame.h"

#include <android/log.h>

#define LOG_TAG "JniLog"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)


extern "C" JNIEXPORT jstring JNICALL
Java_com_waterfairy_mp3lame_SimpleLame_getVersion(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(get_lame_version());
}

int BUFF_SIZE = 4096;


void convertToMp3(FILE *pcmFile, FILE *mp3File, jint inSampleRate,
                  jint inChannels,
                  jint outSampleRate, jint bitrate, jint mode, jint quality) {


    LOGI("hello world");


    // init lame
    lame_global_flags *lameClient;
    lameClient = lame_init();

    // 设置输入文件的采样率
    lame_set_in_samplerate(lameClient, inSampleRate);
    // 设置输出文件的采样率
    lame_set_out_samplerate(lameClient, outSampleRate);
    // 设置通道数
    lame_set_num_channels(lameClient, inChannels);
    // 设置比特率，1411200，44100 * 2 * 16
    lame_set_brate(lameClient, bitrate);
    // 设置质量
    lame_set_quality(lameClient, quality);
    // 设置模式
    lame_set_mode(lameClient, (MPEG_mode) mode);
    lame_init_params(lameClient);

    int bufferSize = 1024 * 512;
    short *buffer = new short[bufferSize / 2];
    short *leftBuffer = new short[bufferSize / 4];
    short *rightBuffer = new short[bufferSize / 4];
    unsigned char *mp3_buffer = new unsigned char[bufferSize];
    size_t readBufferSize = 0;
    // 读PCM文件
    while ((readBufferSize = fread(buffer, 2, bufferSize / 2, pcmFile)) > 0) {
        for (int i = 0; i < readBufferSize; i++) {
            if (i % 2 == 0) {
                leftBuffer[i / 2] = buffer[i];
            } else {
                rightBuffer[i / 2] = buffer[i];
            }
        }
        // 进行MP3编码
        size_t wroteSize = lame_encode_buffer(lameClient, (short int *) leftBuffer, (short int *) rightBuffer,
                                              (int) (readBufferSize / 2), mp3_buffer, bufferSize);
        // 写到文件中
        fwrite(mp3_buffer, 1, wroteSize, mp3File);
    }

    lame_mp3_tags_fid(lameClient, mp3File);
    lame_close(lameClient);
    fclose(pcmFile);
    fclose(mp3File);
}


extern "C" JNIEXPORT void JNICALL Java_com_waterfairy_mp3lame_SimpleLame_wavToMp3
        (JNIEnv *env, jobject obj, jstring wavPath, jstring mp3Path, jint inSampleRate,
         jint inChannels,
         jint outSampleRate, jint bitrate, jint mode, jint quality) {

    jboolean isCopy;
    const char *cWavPath = env->GetStringUTFChars(wavPath, &isCopy);
    const char *cMp3Path = env->GetStringUTFChars(mp3Path, &isCopy);

    // 打开wav文件
    FILE *wavFile = fopen(cWavPath, "rb");

    // 移除wav文件头 4K字节
    fseek(wavFile, 4 * 1024, SEEK_CUR);

    FILE *mp3File = fopen(cMp3Path, "wb+");

    convertToMp3(wavFile, mp3File, inSampleRate, inChannels, outSampleRate, bitrate, mode, quality);
}


extern "C" JNIEXPORT void JNICALL Java_com_waterfairy_mp3lame_SimpleLame_pcmToMp3
        (JNIEnv *env, jobject obj, jstring pcmPath, jstring mp3Path, jint inSampleRate,
         jint inChannels,
         jint outSampleRate, jint bitrate, jint mode, jint quality) {

    jboolean isCopy;
    const char *cPcmPath = env->GetStringUTFChars(pcmPath, &isCopy);
    const char *cMp3Path = env->GetStringUTFChars(mp3Path, &isCopy);

    // 打开pcm文件
    FILE *pcmFile = fopen(cPcmPath, "rb");
    FILE *mp3File = fopen(cMp3Path, "wb+");

    convertToMp3(pcmFile, mp3File, inSampleRate, inChannels, outSampleRate, bitrate, mode, quality);
}